//通用类的实现和测试

#include<iostream>
#include<typeinfo>
#include<cassert>
#include<unistd.h>
#include<any>  //c++17
class Any
{
private:
    class holder
    {
    public:
        virtual ~holder() {}
        virtual const std::type_info& type() = 0;  
        virtual holder *clone() = 0;
    };

    template <class T>
    class placeholder : public holder
    {
    public:
        placeholder(const T& val):_val(val) {};
        //获取子类对象保存的数据类型


        virtual const std::type_info& type()
        {
            return typeid(T);
        }

        //克隆一个新的子类对象
        virtual holder *clone()
        {
            return new placeholder(_val);
        }

    public:
        T _val;
    };
    holder* _content;

    public:
        Any():_content(nullptr) {}

        template<class T>
        Any(const T& val)
        :_content(new placeholder<T>(val))
        {}

        Any(const Any& other)
        :_content(other._content ? other._content->clone() : nullptr){}     //拷贝构造的对象为空就置为空，非空调用拷贝对象的clone


        ~Any()
        {
            delete _content;
        }

        Any& swap(Any& other)
        {
            std::swap(_content,other._content);
            return *this;
        }

        template<class T>
        T* get()   //返回子类对象保存数据的指针
        {
            //获取类型与保存类型必须一致
            assert(typeid(T) == _content->type());
            return &((placeholder<T>*)_content)->_val;   //考虑好优先级  基类指针强转为派生类才能访问派生类对象中存储的数据
        }
        template<class T>
        Any& operator=(const T& val)   //赋值运算符重载函数
        {
            //类似于现代写法
            Any(val).swap(*this);  
            return *this;       //返回引用 为了能连续赋值
        }

        Any& operator=(const Any& other)
        {
            Any(other).swap(*this);
            return *this;
        }

};


//功能测试

//测试是否内存泄漏
class Test
{
public:
    Test()
    {
        std::cout<<"构造"<<std::endl;
    }
    Test(const Test& t)
    {
        std::cout<<"拷贝构造"<<std::endl;
    }
    ~Test()
    {
        std::cout<<"析构"<<std::endl;
    }

};


int main()
{
    
    // {
    // Any a;
    // Test t;
    // a = t;
    // }  //作用域
    
    //c++17的any的使用
    std::any a;
    a = 10;
    int* pi = std::any_cast<int>(&a);
    std::cout<< *pi <<std::endl;
    a = std::string("nihao");
    std::string* ps = std::any_cast<std::string>(&a);
    std::cout<< *ps <<std::endl;

    // a = 10;
    // int* pa = a.get<int>();
    // std::cout<< *pa <<std::endl;

    // a = std::string("nihao");
    // std::string* ps = a.get<std::string>();
    // std::cout<< *ps <<std::endl;
    while(1)sleep(1);

    return 0;
}